using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class OnChargeExplosion : OnChargeObj
{
	public float distanceForEnableGravity;

	public WeaponEffectSettings[] effects;

	public DamageType damageType = DamageType.Explosive;

	public float explosionRadius;

	public bool immidiateDestroyIfMortall;

	public LayerMask layer;

	public bool immediatelyExplosionOnCollision;

	[SerializeField]
	private bool isItArrow;

	public Rigidbody rigid;

	protected Collider objCollider;

	protected Vector3 startPos;

	[SerializeField]
	protected bool addRepForDamage;

	public float maxCameraShakeDistance = 30f;

	private Vector3 startPosition = Vector3.zero;

	private Vector3 startDirection = Vector3.zero;

	protected List<Mortal> damaged = new List<Mortal>();

	public override void Start()
	{
		objCollider = GetComponent<SphereCollider>();
		if (objCollider == null)
		{
			objCollider = GetComponent<BoxCollider>();
		}
		if (ignoreCollider != null && objCollider != null)
		{
			Physics.IgnoreCollision(objCollider, ignoreCollider);
		}
		if (ignoreColliders != null && ignoreColliders.Length > 0)
		{
			for (int i = 0; i < ignoreColliders.Length; i++)
			{
				Physics.IgnoreCollision(objCollider, ignoreColliders[i]);
			}
		}
		if (rigid == null)
		{
			rigid = GetComponent<Rigidbody>();
		}
		if (!base.isMine)
		{
			objCollider.enabled = false;
			rigid.isKinematic = true;
		}
		else
		{
			objCollider.enabled = true;
			rigid.isKinematic = false;
			rigid.useGravity = false;
		}
		startPosition = base.transform.position;
		startDirection = base.transform.forward;
	}

	public void AddForce(Vector3 velocity)
	{
		rigid = GetComponent<Rigidbody>();
		rigid.velocity = velocity * speed;
		rigid.angularVelocity = new Vector3(Random.Range(-1, 1), Random.Range(-1, 1), Random.Range(-1, 1));
		Invoke("BlowUp", lifeTime);
		startPos = base.transform.position;
	}

	public virtual void OnTriggerEnter(Collider other)
	{
		if (!objCollider.isTrigger || !base.isMine)
		{
			return;
		}
		RaycastHit hitInfo = default(RaycastHit);
		Mortal componentInParent = other.gameObject.GetComponentInParent<Mortal>();
		if (componentInParent != null && !damaged.Contains(componentInParent) && (Vector3.Distance(base.transform.position, other.transform.position) <= 1f || Physics.Linecast(base.transform.position, other.transform.position + Vector3.up * 0.1f, out hitInfo, layer) || Physics.Linecast(base.transform.position, other.transform.position + Vector3.up, out hitInfo, layer) || Physics.Linecast(base.transform.position, other.transform.position + Vector3.up * 1.8f, out hitInfo, layer)) && (!(componentInParent is PlayerBehavior) || (!(componentInParent as PlayerBehavior).inCar && !(componentInParent as PlayerBehavior).inHelic)))
		{
			SendDamage(componentInParent, Mathf.Clamp(damage * (1f - hitInfo.distance / explosionRadius) + damage * 0.1f, damage * 0.1f, damage), hitInfo.point);
			damaged.Add(componentInParent);
			if (componentInParent is PlayerBehavior && addRepForDamage && base.ownerId == PlayerBehavior.MyPlayer.ownerId && componentInParent != PlayerBehavior.MyPlayer)
			{
				SessionReputationManager.Instance.AddReputation(1f);
			}
		}
	}

	public virtual void OnCollisionEnter(Collision collision)
	{
		if ((objCollider != null && objCollider.isTrigger) || !base.isMine || (!immediatelyExplosionOnCollision && (!(collision.gameObject.GetComponentInParent<Mortal>() != null) || !immidiateDestroyIfMortall)))
		{
			return;
		}
		rigid.velocity = Vector3.zero;
		rigid.isKinematic = true;
		Vector3 vector = collision.contacts[0].point + collision.relativeVelocity * Time.fixedDeltaTime;
		if (!isItArrow)
		{
			RaycastHit hitInfo;
			if (Physics.Raycast(vector, startDirection, out hitInfo))
			{
				vector = hitInfo.point;
			}
			if (Vector3.Dot(startDirection, base.transform.position - startPosition) < 0f)
			{
				vector = startPosition;
			}
			base.transform.position = vector;
		}
		StopAllCoroutines();
		BlowUp();
	}

	public override IEnumerator UpdateCharge()
	{
		while (!base.isMine || !(Vector3.Distance(startPos, base.transform.position) > distanceForEnableGravity) || !(rigid != null))
		{
			yield return null;
		}
		rigid.useGravity = true;
		if (distanceForEnableGravity > 0f)
		{
			rigid.velocity *= 0.2f;
		}
	}

	public virtual void BlowUp()
	{
		CameraModeControl.instance.ShakeCameraExplosion(base.transform, maxCameraShakeDistance);
		StartCoroutine(Explosion());
	}

	public virtual IEnumerator Explosion()
	{
		yield return new WaitForSeconds(0.05f);
		if (objCollider == null)
		{
			PhotonNetwork.Destroy(base.gameObject);
			yield break;
		}
		objCollider.enabled = true;
		Physics.IgnoreCollision(objCollider, ignoreCollider, false);
		objCollider.isTrigger = true;
		if (objCollider is SphereCollider)
		{
			(objCollider as SphereCollider).radius = explosionRadius;
		}
		wait = null;
		yield return new WaitForSeconds(0.1f);
		PhotonNetwork.Destroy(base.gameObject);
	}

	public void SendDamage(Mortal obj, float damage, Vector3 hitPoint, bool isHeadshot = false)
	{
		if (!obj || (obj is PlayerBehavior && GameController.instance.curTypeGame == TypeGame.WalkingRobots))
		{
			return;
		}
		if (TDMController.isTeamGameType && base.photonView.isMine)
		{
			if (obj is EntityBehavior)
			{
				EntityBehavior entityBehavior = obj as EntityBehavior;
				PlayerBehavior playerBehavior = entityBehavior.getMainHuman() as PlayerBehavior;
				PlayerBehavior playerBehavior2 = GameController.instance.FindPlayer(entityBehavior.photonView.ownerId);
				if ((entityBehavior.getMainHuman() != null && playerBehavior != null && playerBehavior.localTeam == TDMController.myTeam && !entityBehavior.isMine) || (entityBehavior.privateCar && playerBehavior2 != null && playerBehavior2.localTeam == TDMController.myTeam))
				{
					return;
				}
			}
			else if (obj is PlayerBehavior)
			{
				PlayerBehavior playerBehavior3 = obj as PlayerBehavior;
				if (playerBehavior3.localTeam == TDMController.myTeam && !playerBehavior3.isMine)
				{
					return;
				}
			}
		}
		GameController.instance.playerScript.SetPlayerLastDamageInfo(obj, isHeadshot);
		if (!obj.isDead && PlayerBehavior.MyPlayer != obj)
		{
			WalkWindow.instance.aimHUD.ShowAimHit(damage, base.damage);
			if (!isHeadshot)
			{
				obj.ShowNormalDamage();
			}
		}
		if (settings.offlineMode)
		{
			obj.GetDamage((int)damage, (int)damageType, GameController.instance.playerScript.viewId, base.transform.position, hitPoint);
		}
		else if (base.isMine)
		{
			int num = ((!obj.CheckDead((int)damage, (int)damageType)) ? ((int)damage) : (obj.maxHealth + obj.maxArmor));
			obj.GetDamage(num, (int)damageType, GameController.instance.playerScript.viewId, PlayerBehavior.MyPlayer.transform.position, hitPoint);
		}
		if (effects != null)
		{
			WeaponEffectSettings[] array = effects;
			foreach (WeaponEffectSettings weaponEffectSettings in array)
			{
				obj.AddWeaponEffect((int)weaponEffectSettings.effectType, (int)weaponEffectSettings.damageType, weaponEffectSettings.effectDuration, weaponEffectSettings.effectPower, GameController.instance.playerScript.viewId);
			}
		}
	}

	protected override void OnDestroy()
	{
		base.OnDestroy();
	}
}
